home *** CD-ROM | disk | FTP | other *** search
AmigaBASIC Source Code | 1990-03-01 | 14.5 KB | 615 lines |
- REM - LoadILBM-SaveACBM
- REM - by Carolyn Scheppner CBM 04/86
-
- REM - Modified for PAL/NTSC 07/87
- REM - NOTE: Only PAL ILBMs will be
- REM - displayed in a PAL height
- REM - screen. PAL ILBM's contain
- REM - a PAL screenheight in their
- REM - BMHD pageHeight field
-
- REM - This program loads an IFF ILBM
- REM - (Graphicraft,Deluxe Paint, etc.)
- REM - into a custom screen/window.
- REM - If a Graphicraft color cycling
- REM - chunk (CCRT) is found, it will
- REM - also demo the color cycling.
-
- REM - If the user wishes, the screen
- REM - is then saved in a file format
- REM - (ACBM - Amiga Contiguous BitMap)
- REM - which an AmigaBasic program can
- REM - load more quickly. (LoadACBM)
- REM - The ACBM form is similar to
- REM - an ILBM form, except an ABIT
- REM - chunk replaces the interleaved
- REM - BODY chunk. ABIT contains
- REM - sequential contiguous Amiga
- REM - BitPlane data.
-
- REM - Requires exec, graphics and dos
- REM - .bmaps (Use new ConvertFD)
- REM
-
- Main:
-
- PRINT "LoadILBM-SaveACBM --- ILBM loader and converter"
- PRINT
- PRINT " This program loads and displays an IFF ILBM pic file"
- PRINT "(Graphicraft, DPaint, Images) and optionally saves it"
- PRINT "in ACBM format (see comments for description)."
- PRINT "ACBM files can be loaded more quickly from Basic."
- PRINT
- PRINT " Uncompacted ILBMs (Graphicraft) load fairly quickly but"
- PRINT "compacted ILBMs (DPaint, Images) have long load times."
- PRINT "Screen blanking during the load has been commented out"
- PRINT "so the progress of the load can be monitored."
- PRINT
-
- DIM bPlane&(5), cTabWork%(32), cTabSave%(32)
-
- REM - Must create cycling variables
- REM - because this version of SaveACBM
- REM - always saves a CCRT chunk
- ccrtDir% = 0
- ccrtStart% = 0
- ccrtEnd% = 0
- ccrtSecs& = 0
- ccrtMics& = 0
-
-
- REM - Functions from dos.library
- DECLARE FUNCTION xOpen& LIBRARY
- DECLARE FUNCTION xRead& LIBRARY
- DECLARE FUNCTION xWrite& LIBRARY
- REM - xClose returns no value
-
- REM - Functions from exec.library
- DECLARE FUNCTION AllocMem&() LIBRARY
- REM - FreeMem returns no value
-
- PRINT:PRINT "Looking for bmaps ... ";
- LIBRARY "dos.library"
- LIBRARY "exec.library"
- LIBRARY "graphics.library"
- PRINT "found them."
- PRINT:PRINT "ENTER FILESPECS:"
- PRINT "( Try any ILBM filespec )"
- PRINT "( Do not save ACBM if your disk has less than 41K free )"
- PRINT "( To view ILBM without saving ACBM, enter <RET> for ACBM filespec )"
- PRINT
-
- GetNames:
- INPUT " IFF ILBM filespec";ILBMname$
- IF (ILBMname$ = "") GOTO Mcleanup2
-
- INPUT " ACBM filespec";ACBMname$
- PRINT
-
- REM - Load the IFF ILBM pic
- loadError$ = ""
- GOSUB LoadILBM
- IF loadError$ <> "" THEN GOTO Mcleanup
-
- REM - Demo Graphicraft color cycling
- IF foundCCRT AND ccrtDir% THEN
- REM - Save colors
- FOR kk = 0 TO nColors% -1
- cTabSave%(kk) = PEEKW(colorTab&+(kk*2))
- cTabWork%(kk) = cTabSave%(kk)
- NEXT
-
- REM - Cycle colors
- FOR kk = 0 TO 80
- IF ccrtDir% = 1 THEN
- GOSUB Fcycle
- ELSE
- GOSUB Bcycle
- END IF
-
- CALL LoadRGB4&(sViewPort&,VARPTR(cTabWork%(0)),nColors%)
- REM - Delays approximated
- FOR de1 = 0 TO ccrtSecs& * 3000
- FOR de2 = 0 TO ccrtMics& / 500
- NEXT
- NEXT
- NEXT
-
- REM - Restore colors
- CALL LoadRGB4&(sViewPort&,VARPTR(cTabSave%(0)),nColors%)
- END IF
-
-
- REM - Save screen as ACBM file
- IF (loadError$ = "") AND (ACBMname$<>"") THEN
- saveError$ = ""
- GOSUB SaveACBM
- END IF
-
- Mcleanup:
- FOR de = 1 TO 20000:NEXT
- WINDOW CLOSE 2
- SCREEN CLOSE 2
-
- Mcleanup2:
- LIBRARY CLOSE
- IF loadError$ <> "" THEN PRINT loadError$
- IF saveError$ <> "" THEN PRINT saveError$
-
- END
-
-
- Bcycle: 'Backward color cycle
- cTemp% = cTabWork%(ccrtEnd%)
- FOR jj = ccrtEnd%-1 TO ccrtStart% STEP -1
- cTabWork%(jj+1) = cTabWork%(jj)
- NEXT
- cTabWork%(ccrtStart%) = cTemp%
- RETURN
-
- Fcycle: 'Forward color cycle
- cTemp% = cTabWork%(ccrtStart%)
- FOR jj = ccrtStart%+1 TO ccrtEnd%
- cTabWork%(jj-1) = cTabWork%(jj)
- NEXT
- cTabWork%(ccrtEnd%) = cTemp%
- RETURN
-
-
- LoadILBM:
- REM - Requires the following variables
- REM - to have been initialized:
- REM - ILBMname$ (IFF filename)
-
- REM - init variables
- f$ = ILBMname$
- fHandle& = 0
- mybuf& = 0
- foundBMHD = 0
- foundCMAP = 0
- foundCamg = 0
- foundCCRT = 0
- foundBODY = 0
-
- REM - From include/libraries/dos.h
- REM - MODE_NEWFILE = 1006
- REM - MODE_OLDFILE = 1005
-
- filename$ = f$ + CHR$(0)
- fHandle& = xOpen&(SADD(filename$),1005)
- IF fHandle& = 0 THEN
- loadError$ = "Can't open/find pic file"
- GOTO Lcleanup
- END IF
-
-
- REM - Alloc ram for work buffers
- ClearPublic& = 65537
- mybufsize& = 360
- mybuf& = AllocMem&(mybufsize&,ClearPublic&)
- IF mybuf& = 0 THEN
- loadError$ = "Can't alloc buffer"
- GOTO Lcleanup
- END IF
-
- inbuf& = mybuf&
- cbuf& = mybuf& + 120
- ctab& = mybuf& + 240
-
-
- REM - Should read FORMnnnnILBM
- rLen& = xRead&(fHandle&,inbuf&,12)
- tt$ = ""
- FOR kk = 8 TO 11
- tt% = PEEK(inbuf& + kk)
- tt$ = tt$ + CHR$(tt%)
- NEXT
-
- IF tt$ <> "ILBM" THEN
- loadError$ = "Not standard ILBM pic file"
- GOTO Lcleanup
- END IF
-
- REM - Read ILBM chunks
-
- ChunkLoop:
- REM - Get Chunk name/length
- rLen& = xRead&(fHandle&,inbuf&,8)
- icLen& = PEEKL(inbuf& + 4)
- tt$ = ""
- FOR kk = 0 TO 3
- tt% = PEEK(inbuf& + kk)
- tt$ = tt$ + CHR$(tt%)
- NEXT
-
- IF tt$ = "BMHD" THEN 'BitMap header
- foundBMHD = 1
- rLen& = xRead&(fHandle&,inbuf&,icLen&)
- iWidth% = PEEKW(inbuf&)
- iHeight% = PEEKW(inbuf& + 2)
- iDepth% = PEEK(inbuf& + 8)
- iCompr% = PEEK(inbuf& + 10)
- scrWidth% = PEEKW(inbuf& + 16)
- scrHeight% = PEEKW(inbuf& + 18)
-
- iRowBytes% = iWidth% /8
- scrRowBytes% = scrWidth% / 8
- nColors% = 2^(iDepth%)
-
- REM - Enough free ram to display ?
- AvailRam& = FRE(-1)
- NeededRam& = ((scrWidth%/8)*scrHeight%*(iDepth%+1))+5000
- IF AvailRam& < NeededRam& THEN
- loadError$ = "Not enough free ram"
- GOTO Lcleanup
- END IF
-
- hires& = &H8000
- lace& = &H4
- kk = 1
- IF foundCamg THEN
- IF (camgModes& AND hires&) THEN kk = kk+1
- IF (camgModes& AND lace&) THEN kk = kk+2
- ELSE
- IF scrWidth% >= 640 THEN kk = kk + 1
- IF scrHeight% >= 400 THEN kk = kk + 2
- END IF
-
- SCREEN 2,scrWidth%,scrHeight%,iDepth%,kk
- WINDOW 2,"LoadILBM-SaveACBM",,7,2
-
- REM - Get addresses of structures
- GOSUB GetScrAddrs
-
- REM - Black out screen
- REM CALL LoadRGB4&(sViewPort&,ctab&,nColors%)
-
-
- ELSEIF tt$ = "CMAP" THEN 'ColorMap
- foundCMAP = 1
- rLen& = xRead&(fHandle&,cbuf&,icLen&)
-
- REM - Build Color Table
- FOR kk = 0 TO nColors% - 1
- red% = PEEK(cbuf&+(kk*3))
- gre% = PEEK(cbuf&+(kk*3)+1)
- blu% = PEEK(cbuf&+(kk*3)+2)
- regTemp% = (red%*16)+(gre%)+(blu%/16)
- POKEW(ctab&+(2*kk)),regTemp%
- NEXT
-
-
- ELSEIF tt$ = "CAMG" THEN 'Amiga ViewPort Modes
- foundCamg = 1
- rLen& = xRead&(fHandle&,inbuf&,icLen&)
- camgModes& = PEEKL(inbuf&)
-
-
- ELSEIF tt$ = "CCRT" THEN 'Graphicraft color cycle info
- foundCCRT = 1
- rLen& = xRead&(fHandle&,inbuf&,icLen&)
- ccrtDir% = PEEKW(inbuf&)
- ccrtStart% = PEEK(inbuf& + 2)
- ccrtEnd% = PEEK(inbuf& + 3)
- ccrtSecs& = PEEKL(inbuf& + 4)
- ccrtMics& = PEEKL(inbuf& + 8)
-
-
- ELSEIF tt$ = "BODY" THEN 'BitMap
- foundBODY = 1
-
- IF iCompr% = 0 THEN 'no compression
- FOR rr = 0 TO iHeight% -1
- FOR pp = 0 TO iDepth% -1
- scrRow& = bPlane&(pp)+(rr*scrRowBytes%)
- rLen& = xRead&(fHandle&,scrRow&,iRowBytes%)
- NEXT
- NEXT
-
-
- ELSEIF iCompr% = 1 THEN 'cmpByteRun1
- FOR rr = 0 TO iHeight% -1
- FOR pp = 0 TO iDepth% -1
- scrRow& = bPlane&(pp)+(rr*scrRowBytes%)
- bCnt% = 0
-
- WHILE (bCnt% < iRowBytes%)
- rLen& = xRead&(fHandle&,inbuf&,1)
- inCode% = PEEK(inbuf&)
- IF inCode% < 128 THEN
- rLen& = xRead&(fHandle&,scrRow& + bCnt%, inCode%+1)
- bCnt% = bCnt% + inCode% + 1
- ELSEIF inCode% > 128 THEN
- rLen& = xRead&(fHandle&,inbuf&,1)
- inByte% = PEEK(inbuf&)
- FOR kk = bCnt% TO bCnt% + 257 - inCode%
- POKE(scrRow&+kk),inByte%
- NEXT
- bCnt% = bCnt% + 257 - inCode%
- END IF
- WEND
- NEXT
- NEXT
-
- ELSE
- loadError$ = "Unknown compression algorithm"
- GOTO Lcleanup
- END IF
-
-
- ELSE
- REM - Reading unknown chunk
- FOR kk = 1 TO icLen&
- rLen& = xRead&(fHandle&,inbuf&,1)
- NEXT
- REM - If odd length, read 1 more byte
- IF (icLen& OR 1) = icLen& THEN
- rLen& = xRead&(fHandle&,inbuf&,1)
- END IF
-
- END IF
-
-
- REM - Done if got all chunks
- IF foundBMHD AND foundCMAP AND foundBODY THEN
- GOTO GoodLoad
- END IF
-
- REM - Good read, get next chunk
- IF rLen& > 0 THEN GOTO ChunkLoop
-
- IF rLen& < 0 THEN 'Read error
- loadError$ = "Read error"
- GOTO Lcleanup
- END IF
-
- REM - rLen& = 0 means EOF
- IF (foundBMHD=0) OR (foundBODY=0) OR (foundCMAP=0) THEN
- loadError$ = "Needed ILBM chunks not found"
- GOTO Lcleanup
- END IF
-
-
- GoodLoad:
- loadError$ = ""
-
- REM Load proper Colors
- IF foundCMAP THEN
- CALL LoadRGB4&(sViewPort&,ctab&,nColors%)
- END IF
-
- Lcleanup:
- IF fHandle& <> 0 THEN CALL xClose&(fHandle&)
- IF mybuf& <> 0 THEN CALL FreeMem&(mybuf&,mybufsize&)
-
- RETURN
-
-
-
- SaveACBM:
- REM - Saves current window's screen
- REM - Requires the following variables
- REM - to have been initialized:
- REM - ACBMname$ (ACBM filespec)
- REM - Also, if cycling info is to be stored
- REM - ccrtDir% (1,-1, or 0 = none)
- REM - ccrtStart% (low cycle reg)
- REM - ccrtEnd% (high cycle reg)
- REM - ccrtSecs& (cycle time in seconds)
- REM - ccrtMics& (cycle time in microseconds)
- REM
- REM
- REM - Format of ACBM file:
- REM - LONG "FORM"
- REM - LONG size of rest of file
- REM - LONG "ACBM" (form type)
- REM
- REM - LONG "BMHD" (std IFF BitMap header chunk)
- REM - LONG size of BMHD chunk = 20
- REM - UWORD w (bitmap width in pixels)
- REM - UWORD h (bitmap height)
- REM - WORD x (nw corner) = 0
- REM - WORD y (nw corner) = 0
- REM - UBYTE nPlanes
- REM - UBYTE masking = 0
- REM - UBYTE compression = 0
- REM - UBYTE pad1 = 0
- REM - UWORD transparentColor = 0
- REM - UBYTE xAspect (pixel) = 10
- REM - UBYTE yAspect (pixel) = 11
- REM - WORD pageWidth (screen width in pixels)
- REM - WORD pageHeight (screen height in pixels)
- REM
- REM - LONG "CMAP" (std IFF ColorMap chunk)
- REM - LONG size of CMAP chunk
- REM - UBYTE Sets of 3 UBYTES (red, green, blue)
- REM - (2^nPlanes sets)
- REM - (rgb values LEFT justified in each UBYTE)
- REM
- REM - LONG "CAMG" (Amiga ViewPort Modes)
- REM - LONG size of CAMG chunk
- REM - LONG Mode
- REM
- REM - LONG "CCRT" (Graphicraft color cycle info)
- REM - WORD direction (1,-1, or 0 = none)
- REM - UBYTE start (low cycle reg)
- REM - UBYTE end (high cycle reg)
- REM - LONG seconds (cycle time)
- REM - LONG microseconds (cycle time)
- REM - WORD pad = 0
- REM
- REM (Amiga bitplanes 0, 1, etc)
- REM - LONG "ABIT"
- REM - LONG size of ABIT chunk
- REM - BitPlanes 0 thru nPlanes - 1
- REM - (each is h * (w/8) bytes)
-
-
- REM - init variables
- f$ = ACBMname$
- fHandle& = 0
- mybuf& = 0
-
- filename$ = f$ + CHR$(0)
- fHandle& = xOpen&(SADD(filename$),1006)
- IF fHandle& = 0 THEN
- saveError$ = "Can't open output file"
- GOTO Scleanup
- END IF
-
- REM - Alloc ram for work buffers
- ClearPublic& = 65537
- mybufsize& = 120
- mybuf& = AllocMem&(mybufsize&,ClearPublic&)
- IF mybuf& = 0 THEN
- saveError$ = "Can't alloc buffer"
- GOTO Scleanup
- END IF
-
- cbuf& = mybuf&
-
- REM - Get addresses of screen structures
- GOSUB GetScrAddrs
-
- zero& = 0
- pad% = 0
- aspect% = &Ha0b
-
- REM - Compute chunk sizes
- BMHDsize& = 20
- CMAPsize& = (2^scrDepth%) * 3
- CAMGsize& = 4
- CCRTsize& = 14
- ABITsize& = (scrWidth%/8) * scrHeight% * scrDepth%
- REM - FORMsize& = Chunk sizes + 8 bytes per Chunk header + "ACBM"
- FORMsize& = BMHDsize&+CMAPsize&+CAMGsize&+CCRTsize&+ABITsize&+44
-
- REM - Write FORM header
- tt$ = "FORM"
- wLen& = xWrite&(fHandle&,SADD(tt$),4)
- wLen& = xWrite&(fHandle&,VARPTR(FORMsize&),4)
- tt$ = "ACBM"
- wLen& = xWrite&(fHandle&,SADD(tt$),4)
-
- IF wLen& <= 0 THEN
- saveError$ = "Error writing FORM header"
- GOTO Scleanup
- END IF
-
- REM - Write out BMHD chunk
- tt$ = "BMHD"
- wLen& = xWrite&(fHandle&,SADD(tt$),4)
- wLen& = xWrite&(fHandle&,VARPTR(BMHDsize&),4)
- wLen& = xWrite&(fHandle&,VARPTR(scrWidth%),2)
- wLen& = xWrite&(fHandle&,VARPTR(scrHeight%),2)
- wLen& = xWrite&(fHandle&,VARPTR(zero&),4)
- temp% = (256 * scrDepth%)
- wLen& = xWrite&(fHandle&,VARPTR(temp%),2)
- wLen& = xWrite&(fHandle&,VARPTR(zero&),4)
- wLen& = xWrite&(fHandle&,VARPTR(aspect%),2)
- wLen& = xWrite&(fHandle&,VARPTR(scrWidth%),2)
- wLen& = xWrite&(fHandle&,VARPTR(scrHeight%),2)
-
- IF wLen& <= 0 THEN
- saveError$ = "Error writing BMHD"
- GOTO Scleanup
- END IF
-
- REM - Write CMAP chunk
- tt$ = "CMAP"
- wLen& = xWrite&(fHandle&,SADD(tt$),4)
- wLen& = xWrite&(fHandle&,VARPTR(CMAPsize&),4)
-
- REM - Build IFF ColorMap
- FOR kk = 0 TO nColors% - 1
- regTemp% = PEEKW(colorTab& + (2*kk))
- POKE(cbuf&+(kk*3)),(regTemp% AND &Hf00) / 16
- POKE(cbuf&+(kk*3)+1),(regTemp% AND &Hf0)
- POKE(cbuf&+(kk*3)+2),(regTemp% AND &Hf) * 16
- NEXT
-
- wLen& = xWrite&(fHandle&,cbuf&,CMAPsize&)
-
- IF wLen& <= 0 THEN
- saveError$ = "Error writing CMAP"
- GOTO Scleanup
- END IF
-
- REM - Write CAMG chunk
- tt$ = "CAMG"
- wLen& = xWrite&(fHandle&,SADD(tt$),4)
- wLen& = xWrite&(fHandle&,VARPTR(CAMGsize&),4)
- vpModes& = PEEKW(sViewPort& + 32)
- wLen& = xWrite&(fHandle&,VARPTR(vpModes&),4)
-
- IF wLen& <= 0 THEN
- saveError$ = "Error writing CAMG"
- GOTO Scleanup
- END IF
-
- REM - Write CCRT chunk
- tt$ = "CCRT"
- wLen& = xWrite&(fHandle&,SADD(tt$),4)
- wLen& = xWrite&(fHandle&,VARPTR(CCRTsize&),4)
- wLen& = xWrite&(fHandle&,VARPTR(ccrtDir%),2)
- temp% = (256*ccrtStart%) + ccrtEnd%
- wLen& = xWrite&(fHandle&,VARPTR(temp%),2)
- wLen& = xWrite&(fHandle&,VARPTR(ccrtSecs&),4)
- wLen& = xWrite&(fHandle&,VARPTR(ccrtMics&),4)
- wLen& = xWrite&(fHandle&,VARPTR(pad%),2)
-
- IF wLen& <= 0 THEN
- saveError$ = "Error writing CCRT"
- GOTO Scleanup
- END IF
-
-
-
- REM - Write ABIT chunk, bitplanes
- tt$ = "ABIT"
- wLen& = xWrite&(fHandle&,SADD(tt$),4)
- wLen& = xWrite&(fHandle&,VARPTR(ABITsize&),4)
-
- bpLen& = (scrWidth% / 8) * scrHeight%
- FOR pp = 0 TO scrDepth% -1
- wLen& = xWrite&(fHandle&,bPlane&(pp),bpLen&)
- IF wLen& <= 0 THEN
- saveError$ = "Error writing bit plane"+STR$(pp)
- GOTO Scleanup
- END IF
- NEXT
-
- GoodSave:
- saveError$ = ""
-
- Scleanup:
- IF fHandle& <> 0 THEN CALL xClose&(fHandle&)
- IF mybuf& <> 0 THEN CALL FreeMem&(mybuf&,mybufsize&)
- RETURN
-
-
- GetScrAddrs:
- REM - Get addresses of screen structures
- sWindow& = WINDOW(7)
- sScreen& = PEEKL(sWindow& + 46)
- sViewPort& = sScreen& + 44
- sRastPort& = sScreen& + 84
- sColorMap& = PEEKL(sViewPort& + 4)
- colorTab& = PEEKL(sColorMap& + 4)
- sBitMap& = PEEKL(sRastPort& + 4)
-
- REM - Get screen parameters
- scrWidth% = PEEKW(sScreen& + 12)
- scrHeight% = PEEKW(sScreen& + 14)
- scrDepth% = PEEK(sBitMap& + 5)
- nColors% = 2^scrDepth%
-
- REM - Get addresses of Bit Planes
- FOR kk = 0 TO scrDepth% - 1
- bPlane&(kk) = PEEKL(sBitMap&+8+(kk*4))
- NEXT
- RETURN
-
-
-
-